package com.fz.us.admin.company.service.impl;


import com.fz.us.admin.base.bean.Result;
import com.fz.us.admin.base.service.common.ResultService;
import com.fz.us.admin.base.service.impl.BaseServiceImpl;
import com.fz.us.admin.base.utils.CommonUtil;
import com.fz.us.admin.company.bean.EnumManage;
import com.fz.us.admin.company.dao.AdminDao;
import com.fz.us.admin.company.entity.Admin;
import com.fz.us.admin.company.entity.Company;
import com.fz.us.admin.company.entity.User;
import com.fz.us.admin.company.service.AdminService;
import com.fz.us.admin.company.service.UserService;
import com.fz.us.admin.base.dao.BaseDao;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * Service实现类 - 管理员
 * ============================================================================
 * 版权所有 2016 。
 *
 * @author fallenpanda
 * @version 1.0 2016-07-25 。
 * ============================================================================
 */
@Service
public class AdminServiceImpl extends BaseServiceImpl<Admin, String> implements AdminService {

    @Resource
    private AdminDao adminDao;

    @Override
    public BaseDao<Admin, String> getBaseDao() {
        return adminDao;
    }

    @Resource
    private ResultService resultService;
    @Resource
    private UserService userService;

    public boolean isExistByUsername(String username) {
        return adminDao.isExistByUsername(username);
    }

    public boolean isExistByUsermobile(String usermobile) {
        return adminDao.isExistByUsermobile(usermobile);
    }

    public boolean isExistByUseremail(String useremail) {
        return adminDao.isExistByUseremail(useremail);
    }

    public Admin getAdminByAccount(String account) {
        return adminDao.getAdminByAccount(account);
    }

    public boolean isExistByOpenId(String openId) {
        return adminDao.isExistByOpenId(openId);
    }

    public Admin getAdminByOpenId(String openId) {
        return adminDao.getAdminByOpenId(openId);
    }

    public Admin getWeixinAdminByLastOpenId(String openId) {
        return adminDao.getWeixinAdminByLastOpenId(openId);
    }

    public Result checkUsername(EnumManage.AccountEnum accountEnum, String username) {
        if (StringUtils.isEmpty(username)) {
            return resultService.fail("用户名不能为空！");
        }
        if (EnumManage.AccountEnum.USERNAME.equals(accountEnum)) {
            if (!CommonUtil.isUsername(username)) {
                return resultService.fail("请输入有效的用户名！");
            }
            if (isExistByUsername(username)) {
                return resultService.fail("用户名已被使用！");
            }
            return resultService.success("用户名可用");
        } else if (EnumManage.AccountEnum.MAIL.equals(accountEnum)) {
            if (!CommonUtil.isEmail(username)) {
                return resultService.fail("请输入有效的邮箱地址！");
            }
            if (isExistByUseremail(username)) {
                return resultService.fail("邮箱地址已被使用！");
            }
            return resultService.success("邮箱地址可用");
        } else if (EnumManage.AccountEnum.MOBILE.equals(accountEnum)) {
            if (!CommonUtil.isMobile(username)) {
                return resultService.fail("请输入有效的手机号！");
            }
            if (isExistByUsermobile(username)) {
                return resultService.fail("手机号已被使用！");
            }
            return resultService.success("手机号可用");
        } else if (EnumManage.AccountEnum.WEIXIN.equals(accountEnum)) {
            if (isExistByOpenId(username)) {
                return resultService.fail("openId已被使用！");
            }
            return resultService.success("openId可用");
        } else {
            return resultService.fail("错误的账号类型,请联系客服获取帮助！");
        }
    }

    public Admin createAdmin(EnumManage.AccountEnum accountEnum, EnumManage.AccountTypeEnum accountTypeEnum, String username, String password, boolean isEnabled) {
        // 检查账号类型是否有效
        if (accountEnum == null || !ArrayUtils.contains(Admin.ACCOUNT_PASSWORD, accountEnum)) {
            return null;
        }

        // 创建 Admin 对象
        Admin admin = new Admin();
        if (EnumManage.AccountEnum.USERNAME.equals(accountEnum)) {
            admin.setUsername(username);
            admin.setIsUsernameEnabled(isEnabled);
        } else if (EnumManage.AccountEnum.MAIL.equals(accountEnum)) {
            admin.setUseremail(username);
            admin.setIsEmailEnabled(isEnabled);
        } else if (EnumManage.AccountEnum.MOBILE.equals(accountEnum)) {
            admin.setUsermobile(username);
            admin.setIsMobileEnabled(isEnabled);
        }
        admin.setAccountEnum(accountEnum);

        admin.setSalt(new SecureRandomNumberGenerator().nextBytes().toHex());
        admin.setSecret(new SecureRandomNumberGenerator().nextBytes().toHex());

        admin.setIsAccountEnabled(true);
        admin.setIsAccountExpired(false);
        admin.setIsAccountLocked(false);
        admin.setIsCredentialsExpired(false);
        admin.setAccountTypeEnum(accountTypeEnum);
        // 保存
        save(admin);

        // 密码使用 uid + salt 进行加密
        String encodedPassword = encodedPassword(admin.getId(), password, admin.getSalt());
        admin.setPassword(encodedPassword);
        update(admin);

        return admin;
    }

    public Admin createAdmin(EnumManage.AccountEnum accountEnum, EnumManage.AccountTypeEnum accountTypeEnum, String username, String password) {
        return createAdmin(accountEnum, accountTypeEnum, username, password, false);
    }

    public Admin createAdmin(String openId) {
        // 创建 Admin 对象
        Admin admin = new Admin();
        admin.setAccountEnum(EnumManage.AccountEnum.WEIXIN);
        admin.setOpenId(openId);

        admin.setSalt(new SecureRandomNumberGenerator().nextBytes().toHex());
        admin.setSecret(new SecureRandomNumberGenerator().nextBytes().toHex());

        admin.setIsAccountEnabled(true);
        admin.setIsAccountExpired(false);
        admin.setIsAccountLocked(false);
        admin.setIsCredentialsExpired(false);
        admin.setAccountTypeEnum(EnumManage.AccountTypeEnum.User);
        // 保存
        save(admin);
        return admin;
    }

    public void setExpiredDate(Admin admin, Date expireDate) {
        admin.setExpireDate(expireDate);
        update(admin);
    }

    public String encodedPassword(String uid, String password, String salt) {
        String algorithmName = "SHA-256";
        int hashIterations = 2;
        SimpleHash hash = new SimpleHash(algorithmName, password, uid + salt, hashIterations);
        return hash.toHex();
    }

    public boolean validPassword(Admin admin, String password) {
        if (StringUtils.isEmpty(password) || StringUtils.isEmpty(admin.getSalt())) {
            return false;
        }

        // 密码使用 uid + salt 进行加密
        String encodedPassword = encodedPassword(admin.getId(), password, admin.getSalt());
        return StringUtils.equals(admin.getPassword(),encodedPassword);
    }

    public Result updatePassword(Admin admin, String password) {
        // 更新凭证
        admin.setSalt(new SecureRandomNumberGenerator().nextBytes().toHex());
        admin.setSecret(new SecureRandomNumberGenerator().nextBytes().toHex());
        // 重新加密密码
        String encodedPassword = encodedPassword(admin.getId(), password, admin.getSalt());
        admin.setPassword(encodedPassword);
        update(admin);
        return resultService.success();
    }

    public Result updateUsername(Admin admin, String username) {
        if (EnumManage.AccountEnum.MAIL.equals(admin.getAccountEnum())||
                EnumManage.AccountEnum.MOBILE.equals(admin.getAccountEnum())) {
            Result result = checkUsername(EnumManage.AccountEnum.USERNAME, username);
            if (result.getState() == 0) {
                return result;
            }
            if (admin.getIsUsernameEnabled()!=null && admin.getIsUsernameEnabled()) {
                return resultService.fail("用户名不可修改！");
            }
            admin.setUsername(username);
            admin.setIsUsernameEnabled(true);
            update(admin);
            return resultService.success();
        }
        return resultService.fail();
    }

    public Result enableUsermobile(Admin admin) {
        if (StringUtils.isNotEmpty(admin.getUsermobile()) && CommonUtil.isMobile(admin.getUsermobile())) {
            admin.setIsMobileEnabled(true);
            update(admin);
            return resultService.success();
        }
        return resultService.fail();
    }

    public Result disableUsermobile(Admin admin) {
        if ((StringUtils.isNotEmpty(admin.getUsername()) && admin.getIsUsernameEnabled() != null && admin.getIsUsernameEnabled()) ||
                (StringUtils.isNotEmpty(admin.getUseremail()) && admin.getIsEmailEnabled() != null && admin.getIsEmailEnabled())) {
            admin.setUsermobile(null);
            admin.setIsMobileEnabled(false);
            update(admin);
            return resultService.success();
        }
        return resultService.fail("请确保至少设置了用户名或邮箱,以用于登录!");
    }

    public Result updateUsermobile(Admin admin, String mobile) {
        if (CommonUtil.isMobile(mobile)) {
            admin.setUsermobile(mobile);
            admin.setIsMobileEnabled(true);
            update(admin);
            return resultService.success();
        }
        return resultService.fail();
    }

    public Result enableUseremail(Admin admin) {
        if (StringUtils.isNotEmpty(admin.getUseremail()) && CommonUtil.isEmail(admin.getUseremail())) {
            admin.setIsEmailEnabled(true);
            update(admin);
            return resultService.success();
        }
        return resultService.fail();
    }

    public Result updateUseremail(Admin admin, String email) {
        if (CommonUtil.isEmail(email)) {
            admin.setUseremail(email);
            admin.setIsEmailEnabled(true);
            update(admin);
            return resultService.success();
        }
        return resultService.fail();
    }

    public Result updateOpenId(Admin admin, String openId) {
        if (StringUtils.isEmpty(openId)) {
            clearOpenId(admin);

            return resultService.success();
        }

        Admin tempAdmin = getAdminByOpenId(openId);
        if (tempAdmin != null) {
            // openId 已存在
            if (StringUtils.equals(admin.getId(), tempAdmin.getId())) {
                // 已绑定
                return resultService.success();
            } else {
                // 未绑定
                clearOpenId(tempAdmin);// 移除已绑定 OpenId

                setOpenId(admin, openId);// 设置 OpenId

                return resultService.success();
            }
        } else {
            setOpenId(admin, openId);// 设置 OpenId

            return resultService.success();
        }
    }

    public void setOpenId(Admin admin, String openId) {
        if (StringUtils.isNotEmpty(admin.getOpenId())) {
            admin.setLastOpenId(admin.getOpenId());
        }
        admin.setOpenId(openId);
        update(admin);
    }

    public void clearOpenId(Admin admin) {
        if (StringUtils.isNotEmpty(admin.getOpenId())) {
            admin.setLastOpenId(admin.getOpenId());
        }
        admin.setOpenId(null);
        update(admin);
    }

    @Override
    public Company getCompanyByAdminType() {
        Admin admin=get("accountTypeEnum", EnumManage.AccountTypeEnum.Manager);
        User user = userService.getUserByAdminId(admin.getId());
        return  user.getCompany();
    }

    @Override
    public void ResetPass(Admin admin, String password) {
        // 密码使用 uid + salt 进行加密
        String encodedPassword = encodedPassword(admin.getId(), password, admin.getSalt());
        admin.setPassword(encodedPassword);
        update(admin);
    }


}
